package org.aplikator.client.shared.rpc.marshaller;

import org.aplikator.client.shared.data.ListItem;
import org.aplikator.client.shared.descriptor.PropertyDTO;
import org.jboss.errai.marshalling.client.api.MarshallingSession;
import org.jboss.errai.marshalling.client.api.annotations.ClientMarshaller;
import org.jboss.errai.marshalling.client.api.annotations.ServerMarshaller;
import org.jboss.errai.marshalling.client.api.json.EJObject;
import org.jboss.errai.marshalling.client.api.json.EJValue;
import org.jboss.errai.marshalling.client.marshallers.AbstractNullableMarshaller;

import java.util.List;

@ClientMarshaller(PropertyDTO.class)
@ServerMarshaller(PropertyDTO.class)
@SuppressWarnings("unchecked")
public class PropertyDTOMarshaller extends AbstractNullableMarshaller<PropertyDTO> {

	/*@Override
	public Class<PropertyDTO> getTypeHandled() {
		return PropertyDTO.class;
	}*/

	@Override
	public PropertyDTO[] getEmptyArray() {
		return new PropertyDTO[0];
	}

	@Override
	public PropertyDTO doNotNullDemarshall(EJValue o, MarshallingSession ctx) {
		if (o.isObject() != null) {
			EJObject ejObject = o.isObject();
			PropertyDTO propDTO = new PropertyDTO();
			DemarshallingUtils.clientDescriptorBaseUnMarshall(ejObject, propDTO);
			if (ejObject.containsKey("type")) {
				propDTO.setType(ejObject.get("type").isString().stringValue());
			}			
			if (ejObject.containsKey("size")) {
				propDTO.setSize(ejObject.get("size").isNumber().doubleValue());
			}
			if (ejObject.containsKey("editable")) {
				propDTO.setEditable(ejObject.get("editable").isBoolean().booleanValue());
			}

			if (ejObject.containsKey("noChange")) {
				propDTO.setEditable(ejObject.get("noChange").isBoolean().booleanValue());
			}

			if (ejObject.containsKey("listValues")) {
				List listUnMarshall = DemarshallingUtils.listUnMarshall(ejObject.get("listValues"), ctx, ListItem.class.getName());
				propDTO.setListValues(listUnMarshall);
			}

			if (ejObject.containsKey("refferedThrough")) {
				propDTO.setRefferedThrough(this.demarshall(ejObject.get("refferedThrough"), ctx));
			}
			
			return propDTO;
			
		} else return null;
		
	}

	@Override
	public String doNotNullMarshall(PropertyDTO o, MarshallingSession ctx) {
		StringBuilder builder = new StringBuilder().append('{');
		MarshallingUtils.clientDescriptorBase(builder, o).append(',');
		if (o.getType() != null) {
			MarshallingUtils.string("type", o.getType(), builder).append(',');	
		}
		if (o.getSize() != 0.0 ) {
			MarshallingUtils.number("size", o.getSize(), builder).append(',');
		}
		MarshallingUtils.bool("editable", o.isEditable(), builder).append(',');
		MarshallingUtils.bool("noChange", o.isNoChange(), builder);
		if (o.getListValues() != null) {
			builder.append(',');
			MarshallingUtils.key("listValues", builder).append(':');
			MarshallingUtils.listMarshall(builder, o.getListValues(), ctx, ListItem.class.getName());
		}
		if (o.getRefferedThrough() != null) {
			if (!builder.toString().endsWith(",")) {
				builder.append(',');
			}
			MarshallingUtils.key("refferedThrough", builder).append(':');
			builder.append(this.marshall(o.getRefferedThrough(), ctx));
		}
		builder.append('}');
		return builder.toString();
	}
}
